/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package application;

import application.beans.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 *
 * @author Étienne
 */
public class Facade 
{
     /**
     * Fonction servant à aller chercher des professeurs dans la base de données
     * selon le domaine d'étude.
     * @param domaine
     * @return 
     */
    public List<CompteBean> chercherProfesseurs(String domaine){
        CompteDAO dao = new CompteDAO();
        List<CompteBean> resultats = new ArrayList<CompteBean>();
        List<Compte> temp = dao.chercherProfesseurs(domaine);
        
        for(Compte compte: temp){
            resultats.add(compte.asBean());
            Collections.reverse(compte.getMessagesInternes());
        }
        
        return resultats;
    }
    
    /**
     * Procédure qui va mettre un message interne pour un compte comme étant lu.
     * @param idCompte
     * @param idMessage 
     */
    public void lireMessageInterne(Integer idCompte, Integer idMessage){
        MessageInterneDAO dao = new MessageInterneDAO();
        dao.lireMessageInterne(idCompte, idMessage);
    }
    
     /**
     * Fonction qui va chercher le bean d'un compte à partir de son id, 
     * passé en paramètre.
     * @param id
     * @return CompteBean
     */
    public CompteBean chercherCompte(Integer id){
        CompteDAO dao = new CompteDAO();
        Compte c = dao.chercherCompte(id); 
        CompteBean bean = null;
        if(c != null){
            // Si c'est un professeur, ses cours sont ceux qu'il enseigne
            if(c.getStatut().equals("professeur")){
                c.setCours(dao.chercherCoursProfesseur(c.getIdCompte()));
            }
            
            bean = c.asBean();
            /*
             * On passe à travers les messages internes pour trouver ceux 
             * qui ont été lus
             */
            for(MessageInterneBean mesInt:bean.getMessagesInternes()){
                mesInt.setMessageLu(chercherSiMessageLu(
                        mesInt.getIdMessageInterne(), bean.getIdCompte()));
            }
        }
        return bean;
    }
    
    /**
     * Fonction qui va chercher le bean d'un compte selon le nom d'usager passé 
     * en paramètre.
     * @param username
     * @return 
     */
    public CompteBean chercherCompteUsername(String username){
        CompteDAO dao = new CompteDAO();
        Compte c = dao.chercherAvecUsername(username);
        CompteBean bean = null;
        if(c != null){
            // Si c'est un professeur, ses cours sont ceux qu'il enseigne
            if(c.getStatut().equals("professeur")){
                c.setCours(dao.chercherCoursProfesseur(c.getIdCompte()));
            }
            
            bean = c.asBean();
            /*
             * On passe à travers les messages internes pour trouver 
             * ceux qui ont été lus
             */
            for(MessageInterneBean mesInt:bean.getMessagesInternes()){
                mesInt.setMessageLu(chercherSiMessageLu(
                        mesInt.getIdMessageInterne(), bean.getIdCompte()));
            }
            
        }
        
        return bean;
    }
    
    /**
     * Fonction qui va chercher un mot de passe dans la base de données selon
     * l'id passé en paramètre et qui le compare avec le mot de passe passé en 
     * paramètre. Il retourne vrai ou faux selon s'ils sont équivalents.
     * @param id
     * @param password
     * @return booléen 
     */
    public Boolean verifierPassword(Integer id, String password){
        CompteDAO dao = new CompteDAO();
        Boolean pareil;
        String motDePasseCompare = dao.chercherPasswordCompte(id);
        pareil = motDePasseCompare.equals(password);
        return pareil;
    }
    
    /**
     * Procédure qui appelle le DAO pour écrire un message interne dans la 
     * base de données.
     * @param message 
     */
    public void ecrireMessageInterne(MessageInterneBean message,
            List<Integer> destinataires){
        MessageInterneDAO dao = new MessageInterneDAO();
        dao.ecrireMessageInterne(message, destinataires);
    }
    

    /**
     * Fonction qui va chercher si un message à été lu selon l'id du message et
     * du compte passés en paramètre.
     * @param idMessage
     * @param idCompte
     * @return 
     */
    public char chercherSiMessageLu(Integer idMessage, Integer idCompte){
        char messageLu = 'N';
        MessageInterneDAO dao = new MessageInterneDAO();
        
        messageLu = dao.chercherSiMessageLu(idMessage, idCompte);
        return messageLu;
    }
    
    /**
     * Procédure servant à supprimer un lien entre un compte et un message 
     * interne et potentiellement supprimer ce dernier s'il n'a plus de liens
     * pointant vers lui.
     * @param idMessage
     * @param idCompte 
     */
    public void supprimerMessageInterne(Integer idMessage, Integer idCompte){
        MessageInterneDAO dao = new MessageInterneDAO();
        dao.supprimerMessageInterne(idMessage, idCompte);
    }
    
     /**
     * Fonction qui appelle la recherche de comptes dans la base de données 
     * selon le nom et le statut du compte.
     * @param nom
     * @param statut
     * @return les résultats de la recherche
     */
    public List<CompteBean> rechercheComptes(String nom, String statut){
        CompteDAO dao = new CompteDAO();
        List<CompteBean> resultats = new ArrayList<CompteBean>();
        List<Compte> temp = dao.rechercheComptes(nom, statut);
        
        for(Compte compte: temp){
            resultats.add(compte.asBean());
            Collections.reverse(compte.getMessagesInternes());
        }
        
        return resultats;
    }
    
    /**
     * Fonction qui va chercher le bean d'un cours à partir de son id, 
     * passé en paramètre.
     * @param id
     * @return CoursBean
     */
    public CoursBean chercherCours(Integer id){
        CoursDAO dao = new CoursDAO();
        Cours c = dao.chercherCoursID(id); 
        CoursBean bean = null;
        if(c != null){
          bean = c.asBean();  
        }
        return bean;
    }
    
    /**
     * Fonction qui va chercher les comptes dans la base de données selon les
     * informations du compte passé en paramètre.
     * @param criteres
     * @return les comptes trouvés
     */
    public List<CompteBean> rechercheComptesAvancee(CompteBean criteres){
        CompteDAO dao = new CompteDAO();
        List<CompteBean> resultats = new ArrayList<CompteBean>();
        List<Compte> temp = dao.rechercheComptesAvancee(criteres);
        
        for(Compte compte: temp){
            resultats.add(compte.asBean());
        }
        
        return resultats;
    }
    
    /***
     * Procédure qui va écrire un nouveau compte dans la base de données selon
     * les informations dans le compte passé en paramètre.
     * @param infos 
     * @param password 
     */
    public void ecrireCompte(CompteBean infos, String password){
        CompteDAO dao = new CompteDAO();
        dao.ecrireCompte(infos, password);
    }
    
    /***
     * Procédure servant à mettre à jour un compte dans la base de données selon
     * les informations du compte passé en paramètre.
     * @param infos 
     */
    public void miseAJourCompte(CompteBean infos){
        CompteDAO dao = new CompteDAO();
        dao.miseAJourCompte(infos);
    } 
    
    /**
     * Fonction qui appelle la recherche de cours dans la base de données 
     * selon le nom et le domaine passé en paramètre. 
     * @param nom
     * @param domaine
     * @return les résultats de la recherche
     */
    public List<CoursBean> rechercheCours(String nom, String domaine){
        CoursDAO dao = new CoursDAO();
        List<CoursBean> resultats = new ArrayList<CoursBean>();
        List<Cours> temp = dao.rechercheCours(nom, domaine);
        
        for(Cours cours: temp){
            resultats.add(cours.asBean());
        }
        
        return resultats;
    }
    
    /**
     * Fonction qui va chercher les cours dans la base de données selon les
     * informations du cours passé en paramètre.
     * @param criteres
     * @return les cours trouvés
     */
    public List<CoursBean> rechercheCoursAvancee(CoursBean criteres){
        CoursDAO dao = new CoursDAO();
        List<CoursBean> resultats = new ArrayList<CoursBean>();
        List<Cours> temp = dao.rechercheCoursAvancee(criteres);
        
        for(Cours cours: temp){
            resultats.add(cours.asBean());
        }
        
        return resultats;
    }
    
    /***
     * Procédure qui va écrire un nouveau cours dans la base de données selon
     * les informations dans le cours passé en paramètre.
     * @param infos 
     * @param password 
     */
    public void ecrireCours(CoursBean infos){
        CoursDAO dao = new CoursDAO();
        dao.ecrireCours(infos);
    }
    
    /***
     * Procédure servant à mettre à jour un cours dans la base de données selon
     * les informations du cours passé en paramètre.
     * @param infos 
     */
    public void miseAJourCours(CoursBean infos){
        CoursDAO dao = new CoursDAO();
        dao.miseAJourCours(infos);
    } 
    
    /**
     * Fonction qui va gérer l'inscription et la désincription d'un compte à une
     * liste de cours.
     * @param idCompte
     * @param lstCours 
     */
    public void gererInscriptionsCompteACours(Integer idCompte, 
            List<Integer> lstCours){
        CoursDAO dao = new CoursDAO();
        // On supprime d'abord tous les liens entre le compte et ses cours
        dao.supprimerCoursCompte(idCompte);
        if(!lstCours.isEmpty()){
            /*
             * On ajoute tous les liens nécessaires entre le compte 
             * et la liste de cours
             */
            dao.connecterCoursCompte(idCompte, lstCours);
        }
    }
    
    /**
     * Fonction qui va gérer l'inscription et la désinscription d'une liste de
     * comptes à un cours.
     * @param idCours
     * @param lstEleves 
     */
    public void gererInscriptionsElevesACours(Integer idCours, 
            List<Integer> lstEleves){
        CoursDAO dao = new CoursDAO();
        // On supprime d'abord tous les liens entre le cours et ses élèves
        dao.supprimerElevesCours(idCours);
        if(!lstEleves.isEmpty()){
            /*
             * On ajoute tous les liens nécessaires entre le cours 
             * et la liste d'élèves
             */
            dao.connecterElevesCours(idCours, lstEleves);
        }
    }
   
    /**
     * Fonction servant à aller chercher la liste des discussions reliées à un
     * cours selon l'id du cours passé en paramètre.
     * @param idCours
     * @return 
     */
    public List<DiscussionBean> chercherDiscussionsCours(Integer idCours){
        List<DiscussionBean> retour = null;
        CoursDAO dao = new CoursDAO();
        List<Discussion> temp = dao.chercherDiscussionsCours(idCours);
        if(!(temp.isEmpty())){
            retour = new ArrayList<DiscussionBean>();
            for(Discussion courante:temp){
                DiscussionBean bean = courante.asBean();
                retour.add(bean);
            }
        }
        return retour;
    }
    
     /**
     * Méthode qui permet de décoder les caractères spéciaux pour les remplacer
     * par leur équivalent avec accent.
     * @param chaine
     * @return 
     */
    public String decoderChaine(String chaine)
    {
        // On remplace les caractères problématiques par ceux avec accent
        chaine = chaine.replaceAll("Ã¨", "è");
        chaine = chaine.replaceAll("Ã©", "é");  
        chaine = chaine.replaceAll("Ãa", "ê");
        chaine = chaine.replaceAll("Ã®", "î");
        chaine = chaine.replaceAll("Ãʹ", "ô");
        chaine = chaine.replaceAll("Ã©", "ç");
        // On double les apostrophes pour éviter des erreurs avec la requête
        chaine = chaine.replaceAll("'", "''");
        
        return chaine;
    }
    
    /**
     * Méthode qui retourne une liste de dix discussions dont leurs derniers 
     * messages ont été ajoutés récement.
     * @return une liste de discussions
     */
    public ArrayList<DiscussionBean> obtenirRecents()
    {
        ForumDAO dao = new ForumDAO();
        
        ArrayList<DiscussionBean> beans = new ArrayList<DiscussionBean>();
        
        for(Object object : dao.obtenirRecents())
        {
            beans.add(((Discussion)object).asBean());
        }
        
        return beans;
    }
    
    /**
     * Méthode qui retourne une liste de toutes les sections.
     * @return une liste de sections
     */
    public ArrayList<SectionBean> obtenirSections()
    {
        ForumDAO dao = new ForumDAO();
        
        ArrayList<SectionBean> beans = new ArrayList<SectionBean>();
        
        for(Object object : dao.obtenirListeSections())
        {
            beans.add(((Section)object).asBean());
        }
        
        return beans;
    }
    
    /**
     * Méthode qui retourne une liste de tous les cours.
     * @return une liste de cours
     */
    public ArrayList<CoursBean> obtenirCours()
    {
        CoursDAO dao = new CoursDAO();
        
        ArrayList<CoursBean> beans = new ArrayList<CoursBean>();
        
        for(Object object : dao.obtenirListeCours())
        {
            beans.add(((Cours)object).asBean());
        }
        
        return beans;
    }
    
    /**
     * Méthode qui retourne une sous-section.
     * @return une sous-section
     */
    public SousSectionBean chercherSousSection(Integer id)
    {
        ForumDAO dao = new ForumDAO();
        return dao.chercherSousSection(id).asBean();
    }
    
    /**
     * Méthode qui retourne une discussion.
     * @return une discussion
     */
    public DiscussionBean chercherDiscussion(Integer id)
    {
        ForumDAO dao = new ForumDAO();
        return dao.chercherDiscussion(id).asBean();
    }
    
    /**
     * Méthode qui retourne une liste de discussion dont le titre ou un message
     * contient la chaîne de caractères recherchée.
     * @return une discussion
     */
    public ArrayList<DiscussionBean> rechercherDiscussion(String recherche)
    {
        ForumDAO dao = new ForumDAO();
        
        List discussionsTrouve = dao.rechercherDiscussions(recherche);
        ArrayList<DiscussionBean> discussions = new ArrayList<DiscussionBean>();
        
        for(Object discussion : discussionsTrouve)
        {
            discussions.add(((Discussion)discussion).asBean());
        }
        return discussions;
    }
    
    /**
     * Méthode qui ajoute une discussion à la base de données.
     * @param bean contient la plupart des informations nécessaires à l'ajout
     * de la discussion
     * @param strIdSousSection sous-section dans laquelle la discussion sera
     * ajoutée
     * @param strIdCours cours auquel sera lié la discussion
     * @return l'id de la discussion généré par la BD
     */
    public int ecrireDiscussion(DiscussionBean bean, String strIdSousSection, String strIdCours)
    {
        ForumDAO dao = new ForumDAO();
        
        int idDiscussion = dao.ecrireDiscussion(bean, strIdSousSection, strIdCours);
        dao.incrementerDiscussion(Integer.parseInt(strIdSousSection));
        
        return idDiscussion;
    }
    
    /**
     * Incrémente le nombre de vues d'une discussion de un
     * @param idDiscussion l'id de la discussion
     */
    public void incrementerVues(int idDiscussion)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.incrementerVues(idDiscussion);
    }
    
    /**
     * Méthode qui ajoute un message à la base de données et incrémente le 
     * nombre de message de la discussion.
     * @param bean contient la plupart des informations nécessaires à l'ajout
     * du message
     * @param idDiscussion l'id de la discussion auquel sera lié la discussion
     */
    public void ecrireMessage(MessageBean bean, int idDiscussion)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.ecrireMessage(bean, idDiscussion);
        dao.incrementerMessage(idDiscussion);
    }
    
    /**
     * Méthode qui enlève un message à la base de données et décrémente le 
     * nombre de message de la discussion.
     * @param idMessage l'id du message qui sera supprimé
     * @param idDiscussion l'id de la discussion auquel est lié le message
     */
    public void supprimerMessage(int idMessage, int idDiscussion)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.supprimerMessage(idMessage);
        dao.decrementerMessage(idDiscussion);
    }
    
    /**
     * Méthode qui enlève une discussion et ses messages de la BD.
     * @param idDiscussion l'id de la discussion
     */
    public void supprimerDiscussion(int idDiscussion, int idSousSection)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.supprimerDiscussion(idDiscussion);
        dao.decrementerDiscussion(idSousSection);
    }
    
    /**
     * Méthode qui verrouille une discussion empêchant l'ajout de message aux
     * professeurs et aux étudiants ou qui la déverrouille permettant l'ajout
     * de message aux professeurs et aux étudiants.
     * @param idDiscussion l'id de la discussion
     */
    public void verrouillerDiscussion(int idDiscussion, Boolean verrou)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.verrouillerDiscussion(idDiscussion, verrou);
    }
    
    /**
     * Méthode qui modifie la sous-section auquel la discussion est lié
     * @param idDiscussion l'id de la discussion
     * @param idSousSection l'id de la sous-section
     */
    public void deplacerDiscussion(int idDiscussion, int newIdSousSection, int oldIdSousSection)
    {
        ForumDAO dao = new ForumDAO();
        
        dao.deplacerDiscussion(idDiscussion, newIdSousSection);
        dao.incrementerDiscussion(newIdSousSection);
        dao.decrementerDiscussion(oldIdSousSection);
    }
}
